package com;

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DemoAsyncServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		AsyncContext context = request.startAsync();
		context.setTimeout(60 * 60 * 1000);
		System.out.println(Thread.currentThread().getName() + " main");
		// Servlet 3.0允许对请求进行异步处理，但在这个异步处理过程中，传统的阻塞I/O是允许的。这就会造成一些问题。
		// AsyncContext的start方法会向Servlet容器另外申请一个新的线程（这里往往是Worker线程池），然后在这个新的线程中继续处理请求，而原先的线程将被回收到Worker线程池中。
		// 由此，可以看到，这种方式对性能的改进不大，因为如果新的线程和初始Servlet线程共享同一个线程池的话，相当于闲置了一个线程，但同时又占用了另一个线程，反而造成了线程上下文切换这种资源浪费的情况出现。
        // 为此，在Servlet 3.1中引入了非阻塞IO，通过在HttpServletRequest和HttpServletResponse中分别添加ReadListener和WriterListener方法，可以让我们做到：只有在IO数据满足一定条件时（比如读取/写入已经数据准备好），再进行后续的操作，见DemoAsyncListenerServlet
		context.start(new Runnable(){
            @Override
            public void run() {
            	try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
            	System.out.println(Thread.currentThread().getName() + " sub");
                try {
					context.getResponse().getWriter().write("aaa");
				} catch (IOException e) {
					e.printStackTrace();
				}
                context.complete();
            }});
	}

}
